using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace PhpDocBlockGenerator.Model.Php
{
    public class PhpFolder
    {
        /// <summary>
        /// the options container
        /// </summary>
        private Options _options;

        /// <summary>
        /// the directory-info of that folder
        /// </summary>
        private DirectoryInfo _dirInfo;

        /// <summary>
        /// All files in that folder
        /// </summary>
        private List<PhpFile> _phpFiles = new List<PhpFile>();
        public List<PhpFile> PhpFiles
        {
            get { return _phpFiles; }
            set { _phpFiles = value; }
        }

        /// <summary>
        /// All subfolders in that folder
        /// </summary>
        private List<PhpFolder> _phpSubFolder = new List<PhpFolder>();
        public List<PhpFolder> PhpSubFolder
        {
            get { return _phpSubFolder; }
            set { _phpSubFolder = value; }
        }

        /// <summary>
        /// list of pre collected paths which contains php files
        /// </summary>
        private List<String> _prePaths = new List<String>();

        /// <summary>
        /// The path, where the write operations should happen
        /// </summary>
        private String _targetPath = String.Empty;


        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="sourcePath">path to parse and check files recursively from</param>
        /// <param name="targetPath">path to save the writed files</param>
        /// <param name="depth">maximum depth of folders to check for php files</param>
        /// <param name="prePaths">list of pre collected paths which contains php files
        /// (used to get number of php files before we read them -> progress bar)</param>
        /// <param name="options">the options container</param>
        public PhpFolder(String sourcePath, String targetPath, int depth, IEnumerable<String> prePaths, Options options)
        {
            _dirInfo = new DirectoryInfo(sourcePath);
            _targetPath = targetPath;
            _prePaths = new List<String>(prePaths);
            _options = options;

            // if depth > 0 create, get the actual target path
            if (depth > 0)
            {
                _targetPath = Path.Combine(_targetPath, _dirInfo.Name);
                _prePaths.Add(_dirInfo.Name);
            }

            // search for php-files in this directory
            GetAllPhpFiles();

            // get all subfolders
            if (depth <= _options.Depth)
            {
                GetAllSubFolders(sourcePath, depth + 1, _options.Depth);
            }
        }


        /// <summary>
        /// Searches for PHP-files in the given Path and creates a new
        /// PhpFile-object for each one
        /// </summary>
        public void GetAllPhpFiles()
        {
            int cnt = _dirInfo.GetFiles("*.php").Count();
            if (cnt > 0)
            {
                _options.FoldersWithPhpFiles.Add(_dirInfo.FullName);
                _options.PhpFileCount += cnt;
            }

            foreach (FileInfo fileInfo in _dirInfo.GetFiles("*.php"))
            {
                _phpFiles.Add(new PhpFile(
                    fileInfo.FullName, 
                    _targetPath,
                    fileInfo,
                    _prePaths,
                    _options
                ));
            }
        }

        /// <summary>
        /// Searches for Subfolders in the given Path and creates a new
        /// PhpFolder-object for each one
        /// </summary>
        /// <param name="path">path to search for subfolders</param>
        /// <param name="depth">current depth of folders to search for php files</param>
        /// <param name="maxDepth">maximum depth of folders to search for php files</param>
        public void GetAllSubFolders(String path, int depth, int maxDepth)
        {
            foreach (DirectoryInfo subdirInfo in _dirInfo.GetDirectories())
            {
                _phpSubFolder.Add(new PhpFolder(subdirInfo.FullName, _targetPath, depth, _prePaths, _options));
            }
        }
    }
}
